package cn.melonlib.graphql.model.scalars;

import cn.hutool.core.util.ClassUtil;
import graphql.language.IntValue;
import graphql.language.StringValue;
import graphql.language.Value;
import graphql.schema.Coercing;
import graphql.schema.CoercingParseLiteralException;
import graphql.schema.CoercingParseValueException;
import graphql.schema.CoercingSerializeException;

import static graphql.Assert.assertNotNull;

public class GraphQLEnum implements Coercing<String,String> {

    private String convertImpl(Object input) {
        if(input instanceof Enum e){
            return e.name();
        }else {
            return input.toString();
        }
    }

    @Override
    public String serialize(Object input) {
        String result = convertImpl(input);
        if (result == null) {
            throw new CoercingSerializeException(
                    "Expected type 'Int' but was '" + ClassUtil.getClassName(input,true) + "'."
            );
        }
        return result;
    }

    @Override
    public String parseValue(Object input) {
        String result = convertImpl(input);
        if (result == null) {
            throw new CoercingParseValueException(
                    "Expected type 'Int' but was '" + ClassUtil.getClassName(input,true) + "'."
            );
        }
        return result;
    }

    @Override
    public String parseLiteral(Object input) {
        if (!(input instanceof IntValue)) {
            throw new CoercingParseLiteralException(
                    "Expected AST type 'IntValue' but was '" + ClassUtil.getClassName(input,true) + "'."
            );
        }
        String value = ((StringValue) input).getValue();
        return value;
    }

    @Override
    public Value valueToLiteral(Object input) {
        String result = assertNotNull(convertImpl(input));
        return StringValue.newStringValue(result).build();
    }
}
